#pragma once

#ifndef STATS_H
#define STATS_H

#include "Deck.h"
#include <vector>
#include <algorithm>

class CPokerCombination: public CCards  
{
public:    
    enum Combination 
    {
        Invalid = -1, HighCard = 0, Pair, TwoPair, Set, Straight, Flush, FullHouse, FourOfKind, StraightFlush
    };

    enum Kicker 
    {
        None = 0, Two = 2, Three, Four, Five, Six, Seven, 
        Eight, Nine, Ten, Jack, Queen, King, Ace
    };

    CPokerCombination():
        CCards(5)
        {};

    CPokerCombination(CardsIterator begin):
        CCards(5)
    {
        for (int i = 0; i < 5; i++, begin++)
            mCards.push_back( *begin );
    };

    void check()
    {
        sort();
        if ( isStraightFlush() )
            mCombination = StraightFlush;
        else if ( isFourOfKind() )
            mCombination = FourOfKind;
        else if ( isFullHouse() )
            mCombination = FullHouse;
        else if ( isFlush() )
            mCombination = Flush;
        else if ( isStraight() )
            mCombination = Straight;
        else if ( isSet() )
            mCombination = Set;
        else if ( isTwoPair() )
            mCombination = TwoPair;
        else if ( isPair() )
            mCombination = Pair;
        else if ( isHighCard() )
            mCombination = HighCard;
    };

    bool isStraightFlush()
    {
        return ( isFlush() && isStraight() );
    };

    bool isFourOfKind()
    {
        return ( CCard::equalValue(mCards[0], mCards[3]) || CCard::equalValue( mCards[1], mCards[4] ));
    };

    bool isFullHouse()
    {
        return ( CCard::equalValue(mCards[0], mCards[2]) && CCard::equalValue( mCards[3], mCards[4] )) ||
               ( CCard::equalValue(mCards[0], mCards[1]) && CCard::equalValue( mCards[2], mCards[4] ));
    };
                              
    bool isFlush() 
    {
        for (int i = 0; i < 4; i++)
            if ( mCards[i].getSuit() != mCards[i+1].getSuit() )
                return false;
        return true;
    };

    bool isStraight()
    {
        if ( mCards[4].getValue() == CCard::Ace && mCards[0].getValue() == CCard::Two )
        {
            for (int i = 0; i < 3; i++)
                if ( mCards[i+1].getValue() - mCards[i].getValue() != 1 )
                    return false;
        }
        else
        {
            for (int i = 0; i < 4; i++)
                if ( mCards[i+1].getValue() - mCards[i].getValue() != 1 )
                    return false;
        }

        return true;
    };

    bool isSet()
    {
        for (int i = 0; i < 3; i++)
            if ( CCard::equalValue(mCards[i], mCards[i+2]) )
                return true;
        return false;
    };

    bool isTwoPair()
    {
        int pairCount = 0;
        for (int i = 0; i < 4; i++)
            if ( CCard::equalValue(mCards[i], mCards[i+1]) )
                pairCount++, i++;
        return pairCount >= 2;

    };

    bool isPair()
    {
        for (int i = 0; i < 4; i++)
            if ( CCard::equalValue(mCards[i], mCards[i+1]) )
                return true;
        return false;
    };

    bool isHighCard()
    {
        return true;
    };

//private:
    Combination mCombination;
    Kicker mKicker;
};

typedef std::vector<CPokerCombination> Combinations;
typedef std::vector<CPokerCombination>::const_iterator CombinationsIterator;

class CSequence: public CCards
{
public:
    bool isFlash() 
    {

    };

private:
    
};

#endif  //  STATS_H